package com.ecar.oauth.provider.config;

import com.ecar.oauth.provider.beans.OAuthPasswordEncoder;
import com.ecar.oauth.provider.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;

/**
 * spring security 配置
 * Created by 30 on 2016/12/22.
 */
@Configuration
@EnableWebSecurity
@EnableAuthorizationServer
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Resource
	private UserService userService;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// @formatter:off
		http
			.addFilterBefore(clientCredentialsTokenEndpointFilter(), BasicAuthenticationFilter.class)
			.csrf().disable()
				.authorizeRequests().antMatchers("/oauth/**").permitAll()
			.and()
				.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
			.and()
				.authorizeRequests().anyRequest().denyAll();
		// @formatter:on
	}

	@Override
	public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) {
		super.setAuthenticationConfiguration(authenticationConfiguration);
	}

	@Bean
	public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() throws Exception {
		ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
		filter.setAuthenticationManager(authenticationManagerBean());
		filter.setAuthenticationEntryPoint(authenticationEntryPoint());
		return filter;
	}

//	/**
//	 * 自定义的异常处理类，返回json格式数据
//	 * @return
//	 */
//	@Bean
//	public WebResponseExceptionTranslator webResponseExceptionTranslator() {
//		return new JsonWebResponseExceptionTranslator();
//	}

	/**
	 * entry point 中注入自定义的异常处理
	 * @return
	 * @noinspection UnnecessaryLocalVariable
	 */
	@Bean
	public AuthenticationEntryPoint authenticationEntryPoint() {
		OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
//		authenticationEntryPoint.setExceptionTranslator(webResponseExceptionTranslator());
		return authenticationEntryPoint;
	}

	@Bean
	@Override
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}

	@Bean
	@Primary
	public PasswordEncoder passwordEncoder() {
		return new OAuthPasswordEncoder();
	}
}
